﻿using System;

namespace Patterns.Memento {
    public static class AppliedExample {

        public static void Run() {
            SalesProspect s = new SalesProspect();
            s.Name = "Noel van Halen";
            s.Phone = "(412) 256-0990";
            s.Budget = 25000.0;

            // Store internal state
            ProspectMemory m = new ProspectMemory();
            m.Memento = s.SaveMemento();

            // Continue changing originator
            s.Name = "Leo Welch";
            s.Phone = "(310) 209-7111";
            s.Budget = 1000000.0;

            // Restore saved state
            s.RestoreMemento(m.Memento);
        }
    }

    // "Originator"
    class SalesProspect {
        private string name;
        private string phone;
        private double budget;

        // Properties
        public string Name {
            get { return name; }
            set {
                name = value;
                Console.WriteLine("Name: " + name);
            }
        }

        public string Phone {
            get { return phone; }
            set {
                phone = value;
                Console.WriteLine("Phone: " + phone);
            }
        }

        public double Budget {
            get { return budget; }
            set {
                budget = value;
                Console.WriteLine("Budget: " + budget);
            }
        }

        public SalesMemento SaveMemento() {
            Console.WriteLine("\nSaving state --\n");
            return new SalesMemento(name, phone, budget);
        }

        public void RestoreMemento(SalesMemento memento) {
            Console.WriteLine("\nRestoring state --\n");
            this.Name = memento.Name;
            this.Phone = memento.Phone;
            this.Budget = memento.Budget;
        }
    }

    // "Memento"
    class SalesMemento {
        private string name;
        private string phone;
        private double budget;

        // Constructor
        public SalesMemento(string name, string phone, double budget) {
            this.name = name;
            this.phone = phone;
            this.budget = budget;
        }

        // Properties
        public string Name {
            get { return name; }
            set { name = value; }
        }

        public string Phone {
            get { return phone; }
            set { phone = value; }
        }

        public double Budget {
            get { return budget; }
            set { budget = value; }
        }
    }

    // "Caretaker"
    class ProspectMemory {
        private SalesMemento memento;

        // Property
        public SalesMemento Memento {
            set { memento = value; }
            get { return memento; }
        }
    }
}
